<html>
	<head>
		<title>Express - node web framework</title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
		<script type="text/javascript">

      var _gaq = _gaq || [];
      _gaq.push(['_setAccount', 'UA-25235225-1']);
      _gaq.push(['_trackPageview']);

      (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
      })();

    </script>
		<style>
			#tagline {
			  margin-left: 75px;
			  margin-bottom: 30px;
			  color: rgba(255,255,255,0.7); }
			html {
			  background: #1c1c1c url(images/bg.tile.jpg); }

			body {
			  margin: 0;
			  padding-bottom: 30px;
			  font: 14px/1.4 "Helvetica Neue", "Lucida Grande", "Arial";
			  font-size: 14px;
			  line-height: 1.5;
			  -webkit-font-smoothing: antialiased;
			  background: url(images/bg.jpg) 50% 0 no-repeat;
			  color: #8b8b8b; }

			* {
			  outline: none; }

			em {
			  color: white; }

			a img {
			  border: none !important; }

			a {
			  font-weight: bold;
			  text-decoration: none;
			  color: white;
			  -webkit-transition-property: opacity, -webkit-transform, color, background-color, padding, -webkit-box-shadow;
			  -webkit-transition-duration: 0.15s;
			  -webkit-transition-timing-function: ease-out; }
			  a:hover {
			    opacity: 0.8; }

			h1, h2, h3, h4 {
			  margin: 45px 0 0 0;
			  color: white;
			  text-shadow: 1px 2px 2px rgba(0,0,0,0.6); }

			h3 {
			  font-size: 18px; }
			h4 {
			  margin-left: 10px;
			  font-size: 14px;
			}

			pre {
			  margin: 20px 10px;
			  padding: 25px 20px;
			  background: rgba(0,0,0,0.5);
			  border: 1px solid #323232;
			  -webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
			  -moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
			  -webkit-border-radius: 5px;
			  -moz-border-radius: 5px; }

			code {
			  font-family: "Helvetica Neue", "Lucida Grande", "Arial"; }

			ul {
			  margin: 15px 0;
			  padding: 0 0 0 35px; }
			  ul li {
			    margin: 0;
			    padding: 2px 0;
			    list-style: square; }
          ul li ul {
            margin: 0;
            padding-left: 12px;
          }

      .man-name, #Express { display:none; }

			.sect {
			  margin-left: 40px; }
			img {
			  margin-left: 20px;
			  margin-bottom: 15px;
			}

			#logo {
			  display: block;
			  margin-left: 30%;
			  margin-bottom: 30px;
			  width: 194px;
			  height: 51px;
			  background: url(images/logo.png) 0 0 no-repeat;
			  text-indent: -99999px; }
			  #logo:hover {
			    opacity: 0.7; }
			  #logo:active {
			    opacity: 0.3; }

			#ribbon {
			  position: fixed;
			  top: 0;
			  right: 0;
			  z-index: 2; }

			#wrapper {
			  width: 100%;
			  min-height: 800px;
			  background: url(images/top.png) 0 0 repeat-x; }

			#container {
			  margin: 0 auto;
			  padding-top: 80px;
			  width: 550px; }

			#toc {
				position: fixed;
				top: 0;
				left: 0;
				margin: 0 0 0 15px;
				padding: 15px;
				height: 100%;
				background: rgba(0,0,0,0.2);
				overflow: auto;
				border-right: 1px solid rgba(255,255,255,0.05);
			}
			#toc li {
				padding: 0;
				list-style: none;
			}
			#toc li a {
				font-size: 11px;
			}
			#menu {
			  margin-left: 75px;
			  padding: 0;
			  padding-bottom: 30px; }
			  #menu li {
			    display: inline;
			    list-style: none; }
			    #menu li a {
			      display: block;
			      float: left;
			      margin: 0 2px;
			      padding: 3px 15px;
			      background: rgba(0,0,0,0.2);
			      -webkit-border-radius: 8px;
			      -moz-border-radius: 8px;
			      -webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
			      -moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
			      -webkit-transition-property: opacity, -webkit-transform, color, background-color, -webkit-box-shadow;
			      -webkit-transition-duration: 0.15s;
			      -webkit-transition-timing-function: ease-out; }
			      #menu li a:hover,
			      #menu li a.active {
			        background: rgba(0,0,0,0.5); }
			      #menu li a:active {
			        background: rgba(0,0,0,0.1);
			        -webkit-box-shadow: 1px 1px 1px rgba(0,0,0,0.4);
			        -moz-box-shadow: 1px 1px 1px rgba(0,0,0,0.4); }
		</style>
		<script>
		  $(function(){
		    $('.section').hide();
		    $('.toggle, a.section-title').toggle(function(){
		      $(this).siblings('ul').fadeIn(300);
		      return false;
		    }, function(){
		      $(this).siblings('ul').fadeOut(300);
		      return false;
		    });
		  });
		</script>
	</head>
	<body>
		<a href='http://github.com/visionmedia/express'> 
		  <img alt='Fork me on GitHub' id='ribbon' src='http://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png' /> 
		</a>
		<div id="wrapper">
			<div id="container">
				<a href='http://github.com/visionmedia/express' id='logo'>Express</a> 
				<p id="tagline">
				   High performance, high class web development for
				  <a href="http://nodejs.org">Node.js</a>
				</p>
				<ul id="menu">
					<li><a href="index.html">Home</a></li>
					<li><a href="guide.html">Guide</a></li>
					<li><a href="screencasts.html">Screencasts</a></li>
					<li><a href="applications.html">Applications</a></li>
				</ul>
<h3>Express 1.x to 2.x Migration</h3>

<h3>HTTPS</h3>

<p> Creating an HTTPS server is simply, simply pass the TLS options to <em>express.createServer()</em>:</p>

<pre><code> var app = express.createServer({
     key: ...
   , cert: ...
 });

 app.listen(443);
</code></pre>

<h3>req.header() Referrer</h3>

<p> Previously if anyone was doing something similar to:</p>

<pre><code> req.headers.referrer || req.headers.referer
 req.header('Referrer') || req.header('Referer')
</code></pre>

<p> With the new special-case we may now simply use <em>Referrer</em> which will return either if defined:</p>

<pre><code> req.header('Referrer')
</code></pre>

<h3>res.local(name, val)</h3>

<p> Previously all local variables had to be passed to <em>res.render()</em>, or either <em>app.helpers()</em> or <em>app.dynamicHelpers()</em>, now we may do this at the request-level progressively. The <em>res.local()</em> method accepts a <em>name</em> and <em>val</em>, however the locals passed to <em>res.render()</em> will take precedence.</p>

<p> For example we may utilize this feature to create locals in middleware:</p>

<pre><code> function loadUser(req, res, next) {
   User.get(req.params.id, function(err, user){
     res.local('user', user);
     next();
   });
 }

 app.get('/user/:id', loadUser, function(req, res){
   res.render('user');
 });
</code></pre>

<h3>req.param(name[, defaultValue])</h3>

<p> Previously only <em>name</em> was accepted, so some of you may have been doing the following:</p>

<pre><code> var id = req.param('id') || req.user.id;
</code></pre>

<p> The new <em>defaultValue</em> argument can handle this nicely:</p>

<pre><code> var id = req.param('id', req.user.id);
</code></pre>

<h3>app.helpers() / app.locals()</h3>

<p>  <em>app.locals()</em> is now an alias of <em>app.helpers()</em>, as helpers makes more sense for functions.</p>

<h3>req.accepts(type)</h3>

<p>  <em>req.accepts()</em> now accepts extensions:</p>

<pre><code>  // Accept: text/html
  req.accepts('html');
  req.accepts('.html');
  // =&gt; true

  // Accept: text/*; application/json
  req.accepts('html');
  req.accepts('text/*');
  req.accepts('text/plain');
  req.accepts('application/json');
  // =&gt; true

  req.accepts('image/png');
  req.accepts('png');
  // =&gt; false
</code></pre>

<h3>res.cookie()</h3>

<p> Previously only directly values could be passed, so for example:</p>

<pre><code>res.cookie('rememberme', 'yes', { expires: new Date(Date.now() + 900000) });
</code></pre>

<p>However now we have the alternative <em>maxAge</em> property which may be used to set <em>expires</em> relative to <em>Date.now()</em> in milliseconds, so our example above can now become:</p>

<pre><code>res.cookie('rememberme', 'yes', { maxAge: 900000 });
</code></pre>

<h3>res.download() / res.sendfile()</h3>

<p> Both of these methods now utilize Connect&rsquo;s static file server behind the scenes (actually the previous Express code was ported to Connect 1.0). With this change comes a change to the callback as well. Previously the <em>path</em> and <em>stream</em> were passed, however now only an <em>error</em> is passed, when no error has occurred the callback will be invoked indicating that the file transfer is complete. The callback remains optional:</p>

<pre><code> res.download('/path/to/file');

 res.download('/path/to/file', function(err){
   if (err) {
     console.error(err);
   } else {
     console.log('transferred');
   }
 });
</code></pre>

<p> The <em>stream threshold</em> setting was removed.</p>

<h3>res.render()</h3>

<p> Previously locals were passed as a separate key:</p>

<pre><code> res.render('user', { layout: false, locals: { user: user }});
</code></pre>

<p> In Express 2.0 both the locals and the options are one in the same, meaning you cannot have a local variable named <em>layout</em> as it is reserved for express, however this cleans up the API:</p>

<pre><code> res.render('user', { layout: false, user: user });
</code></pre>

<h3>res.partial()</h3>

<p> Express 2.0 adds the <em>res.partial()</em> method, helpful for rendering partial fragments over WebSockets or Ajax requests etc. The API is identical to the <em>partial()</em> calls within views.</p>

<pre><code> // render a collection of comments
 res.partial('comment', [comment1, comment2]); 

 // render a single comment
 res.partial('comment', comment);
</code></pre>

<h3>partial() locals</h3>

<p> Both <em>res.partial()</em> and the <em>partial()</em> functions accept a single object consisting of both the options and the locals. Previously with Express 1.x you may pass <em>user</em> to a partial, along with <em>date</em> like so:</p>

<pre><code>   partial('user', { object: user, locals: { date: new Date }})
</code></pre>

<p>or perhaps if you preferred not to use the inferred name <em>user</em> you may used a local for this as well:</p>

<pre><code>   partial('user', { locals: { user: user, date: new Date }})
</code></pre>

<p> With recent changes to Express 2.x the object passed is now both, so the following is valid for the <em>object</em> option and locals:</p>

<pre><code>   partial('user', { object: user, date: new Date })
</code></pre>

<p> Or the following which is equivalent, however the local var name is explicitly set to <em>user</em> instead of deduced from the filename.</p>

<pre><code>   partial('user', { user: user, date: new Date })
</code></pre>

<p> When a &ldquo;basic&rdquo; object aka <em>{}</em> or <em>new Object</em> is passed, it is considered options, otherwise it is considered the <em>object</em>. The following are equivalent:</p>

<pre><code>  partial('user', user); 
  partial('user', { object: user }); 
</code></pre>

<h3>Template Engine Compliance</h3>

<p> To comply with Express previously engines needed the following signature:</p>

<pre><code> engine.render(str, options, function(err){});
</code></pre>

<p> Now they must export a <em>compile()</em> function, returning a function which when called with local variables will render the template. This allows Express to cache the compiled function in memory during production.</p>

<pre><code> var fn = engine.compile(str, options);
 fn(locals);
</code></pre>

<h3>View Partial Lookup</h3>

<p> Previously partials were loaded relative to the now removed <em>view partials</em> directory setting, or by default <em>views/partials</em>, now they are relative to the view calling them, read more on <a href="guide.html#view-lookup">view lookup</a>.</p>

<h3>Mime Types</h3>

<p> Express and Connect now utilize the <em>mime</em> module in npm, so to add more use:</p>

<pre><code> require('mime').define({ 'foo/bar': ['foo', 'bar'] });
</code></pre>

<h3>static() middleware</h3>

<p> Previously named <code>staticProvider()</code>, the now <code>static()</code> middleware takes a single directory path, followed by options.</p>

<pre><code> app.use(express.static(__dirname + '/public', { maxAge: oneYear }));
</code></pre>

<p>Previously when using options the <code>root</code> option would be used for this:</p>

<pre><code> app.use(express.staticProvider({ root: __dirname + '/public', maxAge: oneYear }));
</code></pre>
			</div>
		</div>
	</body>
</html>